package mazeAssignment;

import java.awt.Color;
import java.awt.Graphics;

public class MazeGraphNew extends MazeGraph
{
	public static final long serialVersionUID = 1L;
	
	private static final Color COLOR_MAZE_START = Color.RED;
	private static final Color COLOR_MAZE_END = Color.GREEN;
	
	private static final Color COLOR_BUILD1 = Color.YELLOW;
	private static final Color COLOR_BUILD2 = new Color(255, 215, 30);
	private static final Color COLOR_BUILD3 = new Color(240, 140, 0);
	private static final Color COLOR_BUILD4 = Color.CYAN;
	private static final Color COLOR_BUILD_UNKNOWN = Color.PINK;

	private static final Color COLOR_SOLVE_VISITED = Color.BLUE;
	private static final Color COLOR_SOLVE_INVALID = Color.GRAY;
	
	
	public MazeGraphNew(Maze pMaze)
	{
		super(pMaze);
	}
	
	public void paintComponent(Graphics g)
	{
		//Clears the panel
		super.paintComponent(g);
		
		float lMazeXsize = maze.getSizeX();
		float lMazeYsize = maze.getSizeY();
		float lPanelXsize = this.getWidth() - 1;
		float lPanelYsize = this.getHeight() - 1;
		float lPixelsPerXwall = lPanelXsize / lMazeXsize;
		float lPixelsPerYwall = lPanelYsize / lMazeYsize;
		
		
		for(int y = 0; y < lMazeYsize; y++)
		{
			for(int x = 0; x < lMazeXsize; x++)
			{
				Color lElementColor = null;
				
				//Build colors
				if(mDrawBuildColors)
				{
					switch(maze.getBuildState(x, y))
					{
					case 0:
						break;
					case 1:
						lElementColor = COLOR_BUILD1;
						break;
					case 2:
						lElementColor = COLOR_BUILD2;
						break;
					case 3:
						lElementColor = COLOR_BUILD3;
						break;
					case 4:
						lElementColor = COLOR_BUILD4;
						break;
					default:
						lElementColor = COLOR_BUILD_UNKNOWN;
						break;
					}
					
				}
				
				//Solve color, overrides build color.
				switch(maze.getSolveState(x, y))
				{
				case Maze.SOLVE_START:
					lElementColor = COLOR_MAZE_START;
					break;
				case Maze.SOLVE_END:
					lElementColor = COLOR_MAZE_END;
					break;
				case Maze.SOLVE_INVALID:
					lElementColor = COLOR_SOLVE_INVALID;
					break;
				}
				
				//Draw a nice path.
				if(maze.getSolveState(x, y) == Maze.SOLVE_VISITED)
				{
					g.setColor(COLOR_SOLVE_VISITED);
					g.fillRect((int)((x + 0.25) * lPixelsPerXwall), (int)((y + 0.25) * lPixelsPerYwall), (int)Math.ceil(lPixelsPerXwall * 0.5), (int)Math.ceil(lPixelsPerYwall * 0.5));
					
					//North connection
					if(y > 0 && ! maze.getNorth(x, y) && maze.getSolveState(x, y - 1) == Maze.SOLVE_VISITED)
					{
						g.fillRect((int)((x + 0.25) * lPixelsPerXwall), (int)Math.ceil((y - 0.5) * lPixelsPerYwall),(int) Math.ceil(lPixelsPerXwall * 0.5), (int)lPixelsPerYwall);
					}
					//West connection
					if(x > 0 && ! maze.getWest(x, y) && maze.getSolveState(x - 1, y) == Maze.SOLVE_VISITED)
					{
						g.fillRect((int)Math.ceil((x - 0.5) * lPixelsPerXwall), (int)((y + 0.25) * lPixelsPerYwall), (int)lPixelsPerXwall, (int)Math.ceil(lPixelsPerYwall * 0.5));
					}
					
					//Line up nicely with start and end position
					if(y > 0 && ! maze.getNorth(x, y) && (maze.getSolveState(x, y - 1) == Maze.SOLVE_START || maze.getSolveState(x, y - 1) == Maze.SOLVE_END)) {
						g.fillRect((int)((x + 0.25) * lPixelsPerXwall), (int)Math.ceil(y * lPixelsPerYwall), (int)Math.ceil(lPixelsPerXwall * 0.5), (int)Math.ceil(lPixelsPerYwall * 0.5));
					}
					if(x > 0 && ! maze.getWest(x, y) && (maze.getSolveState(x - 1, y) == Maze.SOLVE_START || maze.getSolveState(x - 1, y) == Maze.SOLVE_END)) {
						g.fillRect((int)Math.ceil(x * lPixelsPerXwall), (int)((y + 0.25) * lPixelsPerYwall), (int)Math.ceil(lPixelsPerXwall * 0.5), (int)Math.ceil(lPixelsPerYwall * 0.5));
					}
					if((y + 1) < maze.getSizeY() && ! maze.getSouth(x, y) && (maze.getSolveState(x, y + 1) == Maze.SOLVE_START || maze.getSolveState(x, y + 1) == Maze.SOLVE_END)) {
						g.fillRect((int)((x + 0.25) * lPixelsPerXwall), (int)Math.ceil((y + 0.5) * lPixelsPerYwall), (int)Math.ceil(lPixelsPerXwall * 0.5), (int)Math.ceil(lPixelsPerYwall * 0.5));
					}
					if((x + 1) < maze.getSizeX() && ! maze.getEast(x, y) && (maze.getSolveState(x + 1, y) == Maze.SOLVE_START || maze.getSolveState(x + 1, y) == Maze.SOLVE_END)) {
						g.fillRect((int)Math.ceil((x + 0.5) * lPixelsPerXwall), (int)((y + 0.25) * lPixelsPerYwall), (int)Math.ceil(lPixelsPerXwall * 0.5), (int)Math.ceil(lPixelsPerYwall * 0.5));
					}
				}
				else if(lElementColor != null)
				{
					g.setColor(lElementColor);
					g.fillRect((int)(x * lPixelsPerXwall), (int)(y * lPixelsPerYwall), (int)lPixelsPerXwall + 1, (int)lPixelsPerYwall + 1);
				}
				
				g.setColor(Color.BLACK);
				
				//Walls, done last so they always end up on top of the colors.
				//North
				if(y > 0 && maze.getNorth(x, y))
				{
					g.drawLine((int)(x * lPixelsPerXwall), (int)(y * lPixelsPerYwall), (int)((x + 1) * lPixelsPerXwall), (int)(y * lPixelsPerYwall));
				}
				//West
				if(x > 0 && maze.getWest(x, y))
				{
					g.drawLine((int)(x * lPixelsPerXwall), (int)(y * lPixelsPerYwall), (int)(x * lPixelsPerXwall), (int)((y + 1) * lPixelsPerYwall));
				}
			}
		}

		//Outerwalls
		//North
		g.drawLine(0, 0, (int)lPanelXsize, 0);
		//East
		g.drawLine((int)lPanelXsize, 0, (int)lPanelXsize, (int)lPanelYsize);
		//South
		g.drawLine(0, (int)lPanelYsize, (int)lPanelXsize, (int)lPanelYsize);
		//West
		g.drawLine(0, 0, 0, (int)lPanelYsize);
	}
	
}
